package model

import (
	. "github.com/klen-ygs/gorm-zero/gormc/sql"
	"gorm.io/gorm"
	"fmt"
	// "time"
	// "context"
)

// avoid unused err
var _ = InitField
var _ DaysModel = (*customDaysModel)(nil)

type (
	// DaysModel is an interface to be customized, add more methods here,
	// and implement the added methods in customDaysModel.
	DaysModel interface {
		daysModel
		customDaysLogicModel
	}

	customDaysLogicModel interface {
		WithSession(tx *gorm.DB) DaysModel
		CalcTodayReport() error
		CalcYestodayReport() error
		CalcNDayReport(N int) error
	}

	customDaysModel struct {
		*defaultDaysModel
	}
)

func (c customDaysModel) WithSession(tx *gorm.DB) DaysModel {
	newModel := *c.defaultDaysModel
	c.defaultDaysModel = &newModel
	c.conn = tx
	return c
}

func (c customDaysModel) CalcTodayReport() error {
	// var ctx context.Context
	sql1 := `INSERT INTO days (money, uid, uuid, types, day, create_time)
				SELECT tmp.money, tmp.uid, tmp.uuid, tmp.types, tmp.day, tmp.create_time
				FROM (
				    SELECT
				        SUM(CASE WHEN billingtype = TRUE THEN money ELSE -money END) AS money,
				        uid,
				        uuid,
				        types,
				        DATE(create_time) AS day,
				        NOW() AS create_time
				    FROM utxo
				    WHERE DATE(create_time) = CURDATE()
				    GROUP BY uid
				) AS tmp
				LEFT JOIN days ON days.day = tmp.day AND days.uid = tmp.uid
				WHERE days.day IS NULL;`
	sql2 := `UPDATE days
				JOIN (
				    SELECT
				        SUM(CASE WHEN billingtype = TRUE THEN money ELSE -money END) AS money,
				        uid,
				        uuid,
				        types,
				        DATE(create_time) AS day,
				        NOW() AS create_time
				    FROM utxo
				    WHERE DATE(create_time) = CURDATE()
				    GROUP BY uid
				) AS tmp ON days.day = tmp.day AND days.uid = tmp.uid
				SET days.money = tmp.money,
				    days.uuid = tmp.uuid,
				    days.types = tmp.types,
				    days.create_time = tmp.create_time;`
	err := c.conn.Exec(sql1).Error
	fmt.Println(sql1, err)
	err = c.conn.Exec(sql2).Error
	fmt.Println(sql2, err)
	return err
}

func (c customDaysModel) CalcNDayReport(N int) error {
	// var ctx context.Context
	sql1 := `INSERT INTO days (money, uid, uuid, types, day, create_time)
				SELECT tmp.money, tmp.uid, tmp.uuid, tmp.types, tmp.day, tmp.create_time
				FROM (
				    SELECT
				        SUM(CASE WHEN billingtype = TRUE THEN money ELSE -money END) AS money,
				        uid,
				        uuid,
				        types,
				        DATE(create_time) AS day,
				        NOW() AS create_time
				    FROM utxo
				    WHERE DATE(create_time) = CURDATE() - INTERVAL ? DAY
				    GROUP BY uid
				) AS tmp
				LEFT JOIN days ON days.day = tmp.day AND days.uid = tmp.uid
				WHERE days.day IS NULL;`
	sql2 := `UPDATE days
				JOIN (
				    SELECT
				        SUM(CASE WHEN billingtype = TRUE THEN money ELSE -money END) AS money,
				        uid,
				        uuid,
				        types,
				        DATE(create_time) AS day,
				        NOW() AS create_time
				    FROM utxo
				    WHERE DATE(create_time) = CURDATE() - INTERVAL ? DAY
				    GROUP BY uid
				) AS tmp ON days.day = tmp.day AND days.uid = tmp.uid
				SET days.money = tmp.money,
				    days.uuid = tmp.uuid,
				    days.types = tmp.types,
				    days.create_time = tmp.create_time;`
	err := c.conn.Exec(sql1, N).Error
	fmt.Printf(sql1, N)
	fmt.Println(err)
	err = c.conn.Exec(sql2, N).Error
	fmt.Printf(sql2, N)
	fmt.Println(err)
	return err
}

func (c customDaysModel) CalcYestodayReport() error {
	return c.CalcNDayReport(1)
}
// NewDaysModel returns a model for the database table.
func NewDaysModel(conn *gorm.DB) DaysModel {
	return &customDaysModel{
		defaultDaysModel: newDaysModel(conn),
	}
}

func (m *defaultDaysModel) customCacheKeys(data *Days) []string {
	if data == nil {
		return []string{}
	}
	return []string{}
}
